/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { WorkerManagerImpl } from '../../../../../src/base/internal/pool/worker-manager/worker-manager-impl';
import { PoolConfig } from '../../../../../src/base/internal/pool/worker-pool/pool-config';
import { noop } from '../../../../../src/common/util/noop';
import { WorkerManager } from '../../../../../src/base/internal/pool/worker-manager/worker-manager';
import { WorkLog } from '../../../../../src/base/internal/pool/log-collection/log';
import { Work } from '../../../../../src/base/internal/pool/model/work';
import { Priority } from '../../../../../src/base/internal/pool/enum/priority';
import { TCB } from '../../../../../src/base/internal/pool/model/tcb';
import { TcbStore } from '../../../../../src/base/internal/pool/store/tcb-store';
import { ITCB } from '../../../../../src/base/internal/pool/model/itcb';

describe('test worker manger impl', () => {
  const poolConfig: PoolConfig = {
    maxPoolNum: 2
  };
  const workerManager = new WorkerManagerImpl(poolConfig,
    (workerManager: WorkerManager) => {
      // empty
    },
    (log: WorkLog) => {
      // empty
    });
  test('test createWorker', () => {
    expect(workerManager.createWorker()).toBeTruthy();
    expect(workerManager.createWorker()).toBeTruthy();
    expect(workerManager.createWorker()).toBeFalsy();
  });

  test('test doWork', () => {
    const work = new Work(Priority.FIRST, undefined, '');
    const tcb: TCB = new ITCB(work, noop, false, [], () => {
      // empty
    }, '', '', '');
    TcbStore.add(tcb);
    const workerId = workerManager.getAvailableWorkers()[0];
    workerManager.doWork(work, noop, [], workerId);
    expect(workerManager.getAvailableWorkers().length === 1);
    const work2 = new Work(Priority.FIRST, undefined, '');
    workerManager.doWork(work2, noop, [], workerId);
    expect(workerManager.getAvailableWorkers().length === 1);
  });

  test('test hasAvailableWorkers', () => {
    expect(workerManager.hasAvailableWorkers()).toBeTruthy();
  });

  test('test getAvailableWorkers', () => {
    expect(workerManager.getAvailableWorkers().length === 1).toBeTruthy();
  });

  test('test recycle', () => {
    workerManager.setMaxIdleTime(1);
    workerManager.recycle();
    expect(workerManager.hasAvailableWorkers()).toBeFalsy();
  });

  test('test setMaxIdleTime', () => {
    workerManager.setMaxIdleTime(1000000);
    workerManager.createWorker();
    workerManager.createWorker();
    workerManager.recycle();
    expect(workerManager.getAvailableWorkers().length === 1).toBeTruthy();
  });

  test('test setRecycleInterval', () => {
    workerManager.setMaxIdleTime(1000);
    workerManager.setRecycleInterval(500);
    workerManager.createWorker();
    workerManager.createWorker();
    setTimeout(() => {
      expect(workerManager.hasAvailableWorkers()).toBeFalsy();
    }, 2000);
  });

  test('test clear', () => {
    setTimeout(() => {
      workerManager.createWorker();
      workerManager.createWorker();
      workerManager.clear(() => {
        expect(workerManager.hasAvailableWorkers()).toBeFalsy();
      });
    }, 3000);
  });
});
